﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Collections.Generic;
using System.Windows.Navigation;

namespace LiveEduWizard
{
    public interface IHistoryPhoneApplicationPage
    {
        object NavigateData { set; }
    }

    public class HistoryPhoneApplicationFrame : PhoneApplicationFrame
    {
        struct Pair
        {
            public Pair(Uri source, Object data)
            {
                Source = source;
                Data = data;
            }

            public readonly Uri Source;
            public readonly Object Data;
        }

        private List<Pair> history = new List<Pair>();
        private int historyCursor = -1;

        public HistoryPhoneApplicationFrame()
        {
            Navigated += new System.Windows.Navigation.NavigatedEventHandler(HistoryPhoneApplicationFrame_Navigated);
            BackKeyPress += new EventHandler<System.ComponentModel.CancelEventArgs>(HistoryPhoneApplicationFrame_BackKeyPress);
        }

        void HistoryPhoneApplicationFrame_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (historyCursor > 0 && history[historyCursor].Source == history[historyCursor - 1].Source)
            {
                GoBack();
                e.Cancel = true;
            }
        }

        void HistoryPhoneApplicationFrame_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
        {
            switch (e.NavigationMode)
            {
                case NavigationMode.Back:
                    historyCursor--;
                    break;
                case NavigationMode.Forward:
                    historyCursor++;
                    break;
            }

            if (Content is IHistoryPhoneApplicationPage)
            {
                ((IHistoryPhoneApplicationPage)Content).NavigateData = history[historyCursor].Data;
            }
        }

        public new bool Navigate(Uri source)
        {
            return Navigate(source, null);
        }

        public new void GoBack()
        {
            if (historyCursor > 0)
            {
                if (history[historyCursor].Source == history[historyCursor - 1].Source)
                {
                    if (Content is IHistoryPhoneApplicationPage)
                    {
                        ((IHistoryPhoneApplicationPage)Content).NavigateData = history[--historyCursor].Data;
                    }
                }
                else
                    base.GoBack();
            }
        }

        public new void GoForward()
        {
            if (historyCursor > 0)
            {
                if (history[historyCursor].Source == history[historyCursor + 1].Source)
                {
                    if (Content is IHistoryPhoneApplicationPage)
                    {
                        ((IHistoryPhoneApplicationPage)Content).NavigateData = history[++historyCursor].Data;
                    }
                }
                else
                    base.GoForward();
            }
        }

        public bool Navigate(Uri source, object data)
        {
            if (historyCursor >= 0 && historyCursor < history.Count - 1)
                history.RemoveRange(historyCursor + 1, history.Count - historyCursor);

            if (historyCursor >= 0 && history[historyCursor].Source == source)
            {
                if (history[historyCursor].Data == data)
                    return false;

                history.Add(new Pair(source, data));
                historyCursor++;

                if (Content is IHistoryPhoneApplicationPage)
                {
                    ((IHistoryPhoneApplicationPage)Content).NavigateData = data;
                }               

                return true;
            }

            history.Add(new Pair(source, data));
            historyCursor++;
            
            return base.Navigate(source);
        }
    }
}
